home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / Interfaces&Libraries / Universal / Interfaces / AIncludes / MixedMode.a < prev    next >
Encoding:
Text File  |  1997-08-12  |  13.2 KB  |  390 lines  |  [TEXT/MPS ]

  1. ;
  2. ;    File:        MixedMode.a
  3. ;
  4. ;    Contains:    Mixed Mode Manager Interfaces.
  5. ;
  6. ;    Version:    Technology:    System 7.5
  7. ;                Release:    Universal Interfaces 3.0.1
  8. ;
  9. ;    Copyright:    © 1992-1997 by Apple Computer, Inc., all rights reserved.
  10. ;
  11. ;    Bugs?:        Please include the the file and version information (from above) with
  12. ;                the problem description.  Developers belonging to one of the Apple
  13. ;                developer programs can submit bug reports to:
  14. ;
  15. ;                    devsupport@apple.com
  16. ;
  17. ;
  18.     IF &TYPE('__MIXEDMODE__') = 'UNDEFINED' THEN
  19. __MIXEDMODE__ SET 1
  20.  
  21.     IF &TYPE('__TYPES__') = 'UNDEFINED' THEN
  22.     include 'Types.a'
  23.     ENDIF
  24.  
  25. ;  Mixed Mode constants 
  26. ;  Current Routine Descriptor Version 
  27.  
  28. kRoutineDescriptorVersion        EQU        7
  29. ;  MixedModeMagic Magic Cookie/Trap number 
  30.  
  31. _MixedModeMagic                    EQU        $AAFE
  32. ;  MixedModeState Version for CFM68K Mixed Mode 
  33.  
  34. kCurrentMixedModeStateRecord    EQU        1
  35. ;  Calling Conventions 
  36. ; typedef unsigned short                 CallingConventionType
  37.  
  38.  
  39. kPascalStackBased                EQU        0
  40. kCStackBased                    EQU        1
  41. kRegisterBased                    EQU        2
  42. kD0DispatchedPascalStackBased    EQU        8
  43. kD1DispatchedPascalStackBased    EQU        12
  44. kD0DispatchedCStackBased        EQU        9
  45. kStackDispatchedPascalStackBased EQU    14
  46. kThinkCStackBased                EQU        5
  47. ;  ISA Types 
  48. ; typedef SInt8                         ISAType
  49.  
  50.  
  51. kM68kISA                        EQU        0
  52. kPowerPCISA                        EQU        1
  53. ;  RTA Types 
  54. ; typedef SInt8                         RTAType
  55.  
  56.  
  57. kOld68kRTA                        EQU        $00
  58. kPowerPCRTA                        EQU        $00
  59. kCFM68kRTA                        EQU        $10
  60. ;  Constants for specifing 68k registers 
  61.  
  62. kRegisterD0                        EQU        0
  63. kRegisterD1                        EQU        1
  64. kRegisterD2                        EQU        2
  65. kRegisterD3                        EQU        3
  66. kRegisterD4                        EQU        8
  67. kRegisterD5                        EQU        9
  68. kRegisterD6                        EQU        10
  69. kRegisterD7                        EQU        11
  70. kRegisterA0                        EQU        4
  71. kRegisterA1                        EQU        5
  72. kRegisterA2                        EQU        6
  73. kRegisterA3                        EQU        7
  74. kRegisterA4                        EQU        12
  75. kRegisterA5                        EQU        13
  76. kRegisterA6                        EQU        14                    ; A7 is the same as the PowerPC SP 
  77. kCCRegisterCBit                    EQU        16
  78. kCCRegisterVBit                    EQU        17
  79. kCCRegisterZBit                    EQU        18
  80. kCCRegisterNBit                    EQU        19
  81. kCCRegisterXBit                    EQU        20
  82. ; typedef unsigned short                 registerSelectorType
  83.  
  84. ;  SizeCodes we use everywhere 
  85.  
  86. kNoByteCode                        EQU        0
  87. kOneByteCode                    EQU        1
  88. kTwoByteCode                    EQU        2
  89. kFourByteCode                    EQU        3
  90. ;  Mixed Mode Routine Records 
  91. ; typedef unsigned long                 ProcInfoType
  92.  
  93. ;  Routine Flag Bits 
  94. ; typedef unsigned short                 RoutineFlagsType
  95.  
  96.  
  97. kProcDescriptorIsAbsolute        EQU        $00
  98. kProcDescriptorIsRelative        EQU        $01
  99.  
  100. kFragmentIsPrepared                EQU        $00
  101. kFragmentNeedsPreparing            EQU        $02
  102.  
  103. kUseCurrentISA                    EQU        $00
  104. kUseNativeISA                    EQU        $04
  105.  
  106. kPassSelector                    EQU        $00
  107. kDontPassSelector                EQU        $08
  108.  
  109. kRoutineIsNotDispatchedDefaultRoutine EQU $00
  110. kRoutineIsDispatchedDefaultRoutine EQU    $10
  111.  
  112. kProcDescriptorIsProcPtr        EQU        $00
  113. kProcDescriptorIsIndex            EQU        $20
  114. RoutineRecord            RECORD 0
  115. procInfo                 ds.l    1                ; offset: $0 (0)        ;  calling conventions 
  116. reserved1                 ds.b    1                ; offset: $4 (4)        ;  Must be 0 
  117. ISA                         ds.b    1                ; offset: $5 (5)        ;  Instruction Set Architecture 
  118. routineFlags             ds.w    1                ; offset: $6 (6)        ;  Flags for each routine 
  119. procDescriptor             ds.l    1                ; offset: $8 (8)        ;  Where is the thing we’re calling? 
  120. reserved2                 ds.l    1                ; offset: $C (12)        ;  Must be 0 
  121. selector                 ds.l    1                ; offset: $10 (16)        ;  For dispatched routines, the selector 
  122. sizeof                     EQU *                    ; size:   $14 (20)
  123.                         ENDR
  124. ; typedef struct RoutineRecord *        RoutineRecordPtr
  125.  
  126. ; typedef RoutineRecordPtr *            RoutineRecordHandle
  127.  
  128. ;  Mixed Mode Routine Descriptors 
  129. ;  Definitions of the Routine Descriptor Flag Bits 
  130. ; typedef UInt8                         RDFlagsType
  131.  
  132.  
  133. kSelectorsAreNotIndexable        EQU        $00
  134. kSelectorsAreIndexable            EQU        $01
  135. ;  Routine Descriptor Structure 
  136. RoutineDescriptor        RECORD 0
  137. goMixedModeTrap             ds.w    1                ; offset: $0 (0)        ;  Our A-Trap 
  138. version                     ds.b    1                ; offset: $2 (2)        ;  Current Routine Descriptor version 
  139. routineDescriptorFlags     ds.b    1                ; offset: $3 (3)        ;  Routine Descriptor Flags 
  140. reserved1                 ds.l    1                ; offset: $4 (4)        ;  Unused, must be zero 
  141. reserved2                 ds.b    1                ; offset: $8 (8)        ;  Unused, must be zero 
  142. selectorInfo             ds.b    1                ; offset: $9 (9)        ;  If a dispatched routine, calling convention, else 0 
  143. routineCount             ds.w    1                ; offset: $A (10)        ;  Number of routines in this RD 
  144. routineRecords             ds        RoutineRecord    ; offset: $C (12) <-- really an array of length one ;  The individual routines 
  145. sizeof                     EQU *                    ; size:   $20 (32)
  146.                         ENDR
  147. ; typedef struct RoutineDescriptor *    RoutineDescriptorPtr
  148.  
  149. ; typedef RoutineDescriptorPtr *        RoutineDescriptorHandle
  150.  
  151. ;  68K MixedModeStateRecord 
  152. MixedModeStateRecord    RECORD 0
  153. state1                     ds.l    1                ; offset: $0 (0)
  154. state2                     ds.l    1                ; offset: $4 (4)
  155. state3                     ds.l    1                ; offset: $8 (8)
  156. state4                     ds.l    1                ; offset: $C (12)
  157. sizeof                     EQU *                    ; size:   $10 (16)
  158.                         ENDR
  159. ;  Mixed Mode ProcInfos 
  160.  
  161.                                                             ; Calling Convention Offsets 
  162. kCallingConventionWidth            EQU        4
  163. kCallingConventionPhase            EQU        0
  164. kCallingConventionMask            EQU        $0F                    ; Result Offsets 
  165. kResultSizeWidth                EQU        2
  166. kResultSizePhase                EQU        4
  167. kResultSizeMask                    EQU        $30                    ; Parameter offsets & widths 
  168. kStackParameterWidth            EQU        2
  169. kStackParameterPhase            EQU        6
  170. kStackParameterMask                EQU        $FFFFFFC0            ; Register Result Location offsets & widths 
  171. kRegisterResultLocationWidth    EQU        5
  172. kRegisterResultLocationPhase    EQU        6                    ; Register Parameter offsets & widths 
  173. kRegisterParameterWidth            EQU        5
  174. kRegisterParameterPhase            EQU        11
  175. kRegisterParameterMask            EQU        $7FFFF800
  176. kRegisterParameterSizePhase        EQU        0
  177. kRegisterParameterSizeWidth        EQU        2
  178. kRegisterParameterWhichPhase    EQU        2
  179. kRegisterParameterWhichWidth    EQU        3                    ; Dispatched Stack Routine Selector offsets & widths 
  180. kDispatchedSelectorSizeWidth    EQU        2
  181. kDispatchedSelectorSizePhase    EQU        6                    ; Dispatched Stack Routine Parameter offsets 
  182. kDispatchedParameterPhase        EQU        8                    ; Special Case offsets & widths 
  183. kSpecialCaseSelectorWidth        EQU        6
  184. kSpecialCaseSelectorPhase        EQU        4
  185. kSpecialCaseSelectorMask        EQU        $03F0
  186.  
  187. kSpecialCase                    EQU        $000F                ; (CallingConventionType) 
  188.  
  189.                                                             ; all of the special cases enumerated.  The selector field is 6 bits wide 
  190. kSpecialCaseHighHook            EQU        0
  191. kSpecialCaseCaretHook            EQU        0                    ; same as kSpecialCaseHighHook 
  192. kSpecialCaseEOLHook                EQU        1
  193. kSpecialCaseWidthHook            EQU        2
  194. kSpecialCaseTextWidthHook        EQU        2                    ; same as kSpecialCaseWidthHook 
  195. kSpecialCaseNWidthHook            EQU        3
  196. kSpecialCaseDrawHook            EQU        4
  197. kSpecialCaseHitTestHook            EQU        5
  198. kSpecialCaseTEFindWord            EQU        6
  199. kSpecialCaseProtocolHandler        EQU        7
  200. kSpecialCaseSocketListener        EQU        8
  201. kSpecialCaseTERecalc            EQU        9
  202. kSpecialCaseTEDoText            EQU        10
  203. kSpecialCaseGNEFilterProc        EQU        11
  204. kSpecialCaseMBarHook            EQU        12
  205.  
  206. ;    NOTES ON USING ROUTINE DESCRIPTOR FUNCTIONS
  207. ;    
  208. ;    When calling these routine from classic 68k code there are two possible intentions.
  209. ;
  210. ;    The first is source compatibility with code ported to CFM (either PowerPC or 68k CFM). When
  211. ;    the code is compiled for CFM the functions create routine descriptors that can be used by
  212. ;    the mixed mode manager operating on that machine. When the code is compiled for classic 68k
  213. ;    these functions do nothing so that the code will run on Macintoshes that do not have a
  214. ;    mixed mode manager. The dual nature of these functions is achieved by turning the CFM calls
  215. ;    into "no-op" macros for classic 68k: You can put "NewRoutineDescriptor" in your source,
  216. ;    compile it for any runtime or instruction set architecture, and it will run correctly on the
  217. ;    intended runtime/instruction platform. All without source changes and/or conditional source.
  218. ;    
  219. ;    The other intention is for code that "knows" that it is executing as classic 68k runtime
  220. ;    and is specifically trying to call code of another architecture using mixed mode. Since the
  221. ;    routines were designed with classic <-> CFM source compatibility in mind this second case
  222. ;    is treated special. For classic 68k code to create routines descriptors for use by mixed mode
  223. ;    it must call the "Trap" versions of the routines (NewRoutineDescriptorTrap). These versions
  224. ;    are only available to classic 68k callers: rigging the interfaces to allow calling them
  225. ;    from CFM code will result in runtime failure because no shared library implements or exports
  226. ;    the functions.
  227. ;    
  228. ;
  229. ;    This almost appears seamless until you consider "fat" routine descriptors and the advent of
  230. ;    CFM-68K. What does "fat" mean? CFM-68K is not emulated on PowerPC and PowerPC is not emulated
  231. ;    on CFM-68K. It makes no sense to create a routine descriptor having both a CFM-68K routine
  232. ;    and a PowerPC native routine pointer. Therefore "fat" is defined to be a mix of classic and
  233. ;    CFM for the hardware's native instruction set: on PowerPC fat is classic and PowerPC native,
  234. ;    on a 68k machine with CFM-68K installed fat is classic and CFM-68K.
  235. ;    
  236. ;    By definition fat routine descriptors are only constructed by code that is aware of the 
  237. ;    architecture it is executing as and that another architecture exists. Source compatibility
  238. ;    between code intented as pure classic and pure CFM is not an issue and so NewFatRoutineDescriptor
  239. ;    is not available when building pure classic code.
  240. ;    
  241. ;    NewFatRoutineDescriptorTrap is available to classic code on both PowerPC and CFM-68K. The
  242. ;    classic code can use the code fragment manager routine "FindSymbol" to obtain the address of 
  243. ;    a routine in a shared library and then construct a routine descriptor with both the CFM routine 
  244. ;    and classic    routine.
  245. ;
  246.  
  247.  
  248.     IF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  249. ;
  250. ; pascal UniversalProcPtr NewRoutineDescriptor(ProcPtr theProc, ProcInfoType theProcInfo, ISAType theISA)
  251. ;
  252.     IF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  253.         IMPORT_CFM_FUNCTION NewRoutineDescriptor
  254.     ENDIF
  255.  
  256. ;
  257. ; pascal void DisposeRoutineDescriptor(UniversalProcPtr theProcPtr)
  258. ;
  259.     IF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  260.         IMPORT_CFM_FUNCTION DisposeRoutineDescriptor
  261.     ENDIF
  262.  
  263. ;
  264. ; pascal UniversalProcPtr NewFatRoutineDescriptor(ProcPtr theM68kProc, ProcPtr thePowerPCProc, ProcInfoType theProcInfo)
  265. ;
  266.     IF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  267.         IMPORT_CFM_FUNCTION NewFatRoutineDescriptor
  268.     ENDIF
  269.  
  270.     ELSE
  271. ;  Note that the call to NewFatRoutineDescriptor is undefined. 
  272.     ENDIF
  273.  
  274.     IF TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  275. ;    The "Trap" versions of the MixedMode calls are only for classic 68K clients that 
  276. ;    want to load and use CFM based code.
  277. ;
  278.  
  279. ;
  280. ; pascal UniversalProcPtr NewRoutineDescriptorTrap(ProcPtr theProc, ProcInfoType theProcInfo, ISAType theISA)
  281. ;
  282.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  283.         Macro
  284.         _NewRoutineDescriptorTrap
  285.             moveq               #0,D0
  286.             dc.w                $AA59
  287.         EndM
  288.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  289.         IMPORT_CFM_FUNCTION NewRoutineDescriptorTrap
  290.     ENDIF
  291.  
  292. ;
  293. ; pascal void DisposeRoutineDescriptorTrap(UniversalProcPtr theProcPtr)
  294. ;
  295.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  296.         Macro
  297.         _DisposeRoutineDescriptorTrap
  298.             moveq               #1,D0
  299.             dc.w                $AA59
  300.         EndM
  301.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  302.         IMPORT_CFM_FUNCTION DisposeRoutineDescriptorTrap
  303.     ENDIF
  304.  
  305. ;
  306. ; pascal UniversalProcPtr NewFatRoutineDescriptorTrap(ProcPtr theM68kProc, ProcPtr thePowerPCProc, ProcInfoType theProcInfo)
  307. ;
  308.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  309.         Macro
  310.         _NewFatRoutineDescriptorTrap
  311.             moveq               #2,D0
  312.             dc.w                $AA59
  313.         EndM
  314.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  315.         IMPORT_CFM_FUNCTION NewFatRoutineDescriptorTrap
  316.     ENDIF
  317.  
  318.     ENDIF
  319.     IF TARGET_RT_MAC_CFM THEN
  320. ;    CallUniversalProc is only implemented in shared libraries on CFM68K and PowerPC, it is now
  321. ;    conditionalize with TARGET_RT_MAC_CFM.  This will catch accidental calls from classic 68K code
  322. ;    that previously only showed up as linker errors.
  323. ;
  324.  
  325.     ENDIF    ; TARGET_RT_MAC_CFM
  326.     IF TARGET_CPU_68K THEN
  327. ;
  328. ; pascal OSErr SaveMixedModeState(MixedModeStateRecord *stateStorage, UInt32 stateVersion)
  329. ;
  330.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  331.         Macro
  332.         _SaveMixedModeState
  333.             moveq               #3,D0
  334.             dc.w                $AA59
  335.         EndM
  336.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  337.         IMPORT_CFM_FUNCTION SaveMixedModeState
  338.     ENDIF
  339.  
  340. ;
  341. ; pascal OSErr RestoreMixedModeState(MixedModeStateRecord *stateStorage, UInt32 stateVersion)
  342. ;
  343.     IF TARGET_OS_MAC ** TARGET_CPU_68K ** ¬ TARGET_RT_MAC_CFM THEN
  344.         Macro
  345.         _RestoreMixedModeState
  346.             moveq               #4,D0
  347.             dc.w                $AA59
  348.         EndM
  349.     ELSEIF TARGET_OS_MAC ** TARGET_RT_MAC_CFM THEN
  350.         IMPORT_CFM_FUNCTION RestoreMixedModeState
  351.     ENDIF
  352.  
  353.     ENDIF    ; TARGET_CPU_68K
  354. ;  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
  355. ; *
  356. ; *    Macros for building ProcInfos.  Examples:
  357. ; *    
  358. ; *    
  359. ; *    uppModalFilterProcInfo = kPascalStackBased
  360. ; *         | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
  361. ; *         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DialogPtr)))
  362. ; *         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(EventRecord*)))
  363. ; *         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short*))),
  364. ; *
  365. ; *    uppDeskHookProcInfo = kRegisterBased
  366. ; *         | REGISTER_ROUTINE_PARAMETER(1, kRegisterD0, SIZE_CODE(sizeof(Boolean)))
  367. ; *         | REGISTER_ROUTINE_PARAMETER(2, kRegisterA0, SIZE_CODE(sizeof(EventRecord*)))
  368. ; *
  369. ; *    uppGXSpoolResourceProcInfo = kCStackBased
  370. ; *         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  371. ; *         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(gxSpoolFile)))
  372. ; *         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
  373. ; *         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ResType)))
  374. ; *         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
  375. ; *
  376. ; *    uppTEFindWordProcInfo = SPECIAL_CASE_PROCINFO( 6 ),
  377. ; *
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.     ENDIF ; __MIXEDMODE__ 
  385.  
  386.